package org.zxyj.manage.service.impl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zxyj.core.utils.FileUtil;
import org.zxyj.core.utils.MessageUtil;
import org.zxyj.core.utils.UUIDUtils;
import org.zxyj.manage.entity.CoursePaperCrop;
import org.zxyj.manage.entity.CoursePaperDetail;
import org.zxyj.manage.entity.CourseTemplateArea;
import org.zxyj.manage.service.ICoursePaperService;
import org.zxyj.manage.service.ICropService;
import org.zxyj.core.constants.Dict;
import org.zxyj.core.net.coobird.thumbnailator.Thumbnails;
import org.zxyj.core.net.coobird.thumbnailator.geometry.Positions;

@Service
public class CropServiceImpl implements ICropService{
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
    private ICoursePaperService coursePaperService;
	
	//读取配置文件
    //private static PropertiesUtil configProp = PropertiesUtil.newInstance(Thread.currentThread().getContextClassLoader().getResource("").getPath() + "config/config.properties");
    
    /**
     * 裁剪图片指定区域
     * @param source  源文件路径
     * @param destUrl 输出路径
     * @param imgName 文件名称
     * @param params 参数
     * @return  文件流
     * @throws IOException 
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public BufferedImage cropPosBuffered(String source,Map<String,Integer> params) throws IOException{
        int width = 500;
        int height = 500;
        int start_x = 0;
        int start_y = 0;
        if(params==null){
            //默认起始点从（0，0）开始
        }else{
            width = params.get("width");
            height = params.get("height");
            start_x = params.get("start_x");
            start_y = params.get("start_y");
        }
        //原图裁剪
        BufferedImage bi = imageCropBuffered(width, height, start_x, start_y,source);
        return bi;
    }
    
    /**
     * 裁剪图片指定区域
     * @param source  源文件路径
     * @param destUrl 输出路径
     * @param imgName 文件名称
     * @param params 参数
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public void cropPos(String sourceUrl,String destUrl,String imgName,Map<String,Object> params){
    public void cropPos(Map<String,Object> params){
    	String destUrl = (String) params.get("destUrl");
    	FileUtil.createDir(destUrl);
        //原图裁剪
        try{
        	params.put("destUrl", destUrl+params.get("imgName"));
            imageCropFromUrl(params);
        }catch(Exception e){
            System.out.println(params.get("sourceUrl")+"图片中裁剪特征点位置出错~~~11111！~~~~~~~~~~~~~~~~~~~~");
        }
    }
    
    /**
     * 获取图片裁剪区域图片流
     * @param path 源文件路径
     * @param params
     * @return 图片流
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public BufferedImage getCropImageBuffered(Map<String,Object> params){
        String imgName = UUIDUtils.UUID()+ "."+Dict.IMAGE_FORMAT.PNG;
        String destUrl = MessageUtil.getExtConfig("fj.temp.pic.url");//临时图片存放路径
        params.put("imgName", imgName);
        params.put("destUrl", destUrl);
        cropPos(params);//裁剪特征点区域
        BufferedImage imageBuff = readImageBuffered(destUrl+imgName);//读取文件流
        return imageBuff;
    }
    
    /**
     * 读取路径文件为图片文件流
     * @param picUrl
     * @return
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public BufferedImage readImageBuffered(String picUrl){
        File file = new File(picUrl);
        BufferedImage image = null;
        try{
            image = ImageIO.read(file);
        }catch (IOException e){
            e.printStackTrace();
        }
        return image;
    }
    
    /**
     * 裁剪图片指定区域，返回文件流
     * @param source  源文件路径
     * @param destUrl 输出路径
     * @param imgName 文件名称
     * @param params 参数
     * @return  文件流
     * @throws IOException 
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public BufferedImage cropPosBuffered(BufferedImage source,Map<String,Integer> params) throws IOException{
        int width = 500;
        int height = 500;
        int start_x = 0;
        int start_y = 0;
        if(params==null){
            //默认起始点从（0，0）开始
        }else{
            width = params.get("width");
            height = params.get("height");
            start_x = params.get("start_x");
            start_y = params.get("start_y");
        }
        //原图裁剪
        BufferedImage bi = imageCropBuffered(width, height, start_x, start_y,source);
        return bi;
    }
    
    /**
     * 裁剪图片指定区域，生成文件
     * @param image 图片流
     * @param destUrl 目标输出路径
     * @param imgName 文件名称
     * @param params
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public void cropPos1(BufferedImage image,String destUrl,String imgName,Map<String,Integer> params){
    public void cropPos1(Map<String,Object> params){
    	String destUrl = String.valueOf(params.get("destUrl"));
    	FileUtil.createDir(destUrl);
        /*if(params==null){
            //默认起始点从（0，0）开始
        	params.put("width", Dict.DEFAULT_CROP_LEFT_SIZE.WIDTH);
        	params.put("height", Dict.DEFAULT_CROP_LEFT_SIZE.HEIGHT);
        	params.put("start_x", Dict.DEFAULT_CROP_LEFT_SIZE.START_X);
        	params.put("start_y", Dict.DEFAULT_CROP_LEFT_SIZE.START_Y);
        }*/
        try{
        	params.put("destUrl",destUrl + params.get("imgName"));
            imageCropFromBuff(params);//原图裁剪
        }catch(Exception e){
            System.out.println("图片中裁剪位置出错！~~~~~~~~~~~~~~~~~~~~");
        }
    }
    
    /**
     * 裁剪图片指定区域-从右上角开始裁剪
     * @param source 源文件
     * @param destUrl 目标文件路径
     * @param imgName 文件名称
     * @param params
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public void cropPosRightTop(String source,String destUrl,String imgName){
        File directory = new File(destUrl, destUrl);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        
        int width = 500;
        int height = 500;
        //原图裁剪
        try{
            imageCropRight(width, height, source, destUrl+imgName);
            //ImageMagickTool.cropRight(width,height,start_x,start_y,source, destUrl+imgName);
        }catch(Exception e){
            //System.out.println("width="+width+",height="+height+",source="+source+",desturl="+destUrl+imgName);
            System.out.println("图片中裁剪特征点位置出错---右侧！~~~~~~~~~~~~~~~~~~~~");
            e.printStackTrace();
        }
    }
    
    /**
     * 裁剪图片指定区域-从右上角开始裁剪
     * @param source 源文件
     * @param params
     * @return 文件流
     * @throws NumberFormatException
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public BufferedImage cropPosRightTopBuffered(String source,Map<String,Integer> params) throws NumberFormatException, IOException{
        int width = 500;
        int height = 500;
        int start_x = 0;
        int start_y = 0;
        if(params==null){
            //默认起始点从（0，0）开始
        }else{
            width = params.get("width");
            height = params.get("height");
            start_x = params.get("start_x");
            start_y = params.get("start_y");
        }
        //原图裁剪
        BufferedImage bi = imageCropRight(width, height, start_x, start_y,source);
        return bi;
    }
    
    /**
     * 图片旋转方法-格式转换
     * @param sourceUrl 源文件路径
     * @param rotate 旋转角度
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public BufferedImage imageRotateToBuff(String resourceUrl,double rotate) throws IOException{ 
    public BufferedImage imageRotateToBuff(Map<String, Object> params) throws IOException{ 
        Thumbnails thumbnails = new Thumbnails();
        return thumbnails.of(String.valueOf(params.get("sourceUrl")))
        		.rotate(Double.valueOf(String.valueOf(params.get("rotate"))))
        		.scale(1f).asBufferedImage();
    }
    
    /**
     * 图片旋转方法-原尺寸
     * @param sourceUrl 源文件路径
     * @param destUrl 目标路径
     * @param rotate 旋转角度
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public void imageRotateToFile(String resourceUrl,String destUrl,double rotate) throws IOException{ 
   /* public void imageRotateToFile(Map<String,Object> params) throws IOException{ 
        Thumbnails thumbnails = new Thumbnails();
        thumbnails.of(String.valueOf(params.get("sourceUrl")))
        .rotate(Double.valueOf(String.valueOf(params.get("rotate"))))
        .scale(1f)
        .toFile(String.valueOf(params.get("destUrl")));
    }*/
    
    /**
     * 图片旋转方法-按指定比例缩放存储
     * @param sourceUrl 源文件路径
     * @param destUrl 目标路径
     * @param rotate 旋转角度
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public void imageRotateToFile(String resourceUrl,String destUrl,double rotate,float quality) throws IOException{ 
    public void imageRotateToFile(Map<String,Object> params) throws IOException{ 
        Thumbnails thumbnails = new Thumbnails();
        String sourceUrl = String.valueOf(params.get("sourceUrl"));
        String destUrl = String.valueOf(params.get("destUrl"));
        double rotate = Double.valueOf(String.valueOf(params.get("rotate")));
        float quality = Float.valueOf(String.valueOf(params.get("quality")));
        if(params.containsKey("quality")){
        	thumbnails.of(sourceUrl).rotate(rotate).scale(quality).outputQuality(quality).toFile(destUrl);
        }else{
        	thumbnails.of(sourceUrl).rotate(rotate).scale(1f).toFile(destUrl);
        }
    }
    
    /**
     * 裁剪图片-来源是URL
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @throws IOException 
     */
    //public void imageCropFromUrl(long width1, long height1, long x1, long y1, String source, String dest) throws IOException {
    public void imageCropFromUrl(Map<String,Object> params) throws IOException {
        Thumbnails thumbnails = new Thumbnails();
        String sourceUrl = (String) params.get("sourceUrl");
        String destUrl = (String) params.get("destUrl");
        int defaultStartX = Dict.DEFAULT_POS.START_X;
        int defaultStartY = Dict.DEFAULT_POS.START_Y;
        //指定坐标
        int width = Integer.parseInt(String.valueOf(params.get("width")));
        int height = Integer.parseInt(String.valueOf(params.get("height")));
        int x = Integer.parseInt(String.valueOf(params.get("start_x")))<0?defaultStartX:Integer.parseInt(String.valueOf(params.get("start_x")));
        int y = Integer.parseInt(String.valueOf(params.get("start_y")))<0?defaultStartY:Integer.parseInt(String.valueOf(params.get("start_y")));
        if(x==0 && y==0){
            BufferedImage bi = thumbnails.of(sourceUrl).sourceRegion(x,y,width,height).scale(1f).asBufferedImage();
            BufferedImage inputImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            Graphics graphics = inputImage.getGraphics();
            graphics.setColor(new Color(255, 255, 255));  
            graphics.fillRect(defaultStartX, defaultStartY, width,height);
            graphics.drawImage(bi, defaultStartX, defaultStartY, width,height, null); //画图
            ImageIO.write(inputImage, Dict.IMAGE_FORMAT.PNG, new File(destUrl));
        }else{
            thumbnails.of(sourceUrl).sourceRegion(x,y,width,height).scale(1f).toFile(destUrl);
        }
    }
    
    /**
     * 裁剪图片-来源是URL，对图片质量进行压缩
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @throws IOException 
     */
    //public void imageCropFromUrlQuality(long width1, long height1, long x1, long y1, String source, String dest,String outputQuality) throws IOException {
    public void imageCropFromUrlQuality(Map<String,Object> params) throws IOException {
        Thumbnails thumbnails = new Thumbnails();
        float quality = Float.parseFloat(String.valueOf(params.get("outputQuality")));
        int width = Integer.valueOf(String.valueOf(params.get("width")));
        int height = Integer.valueOf(String.valueOf(params.get("height")));
        int x = Integer.valueOf(String.valueOf(params.get("x1")));
        int y = Integer.valueOf(String.valueOf(params.get("y1")));
        thumbnails.of(String.valueOf(params.get("sourceUrl")))
        .sourceRegion(x,y,width,height)
        .scale(quality)
        .outputQuality(quality)
        .toFile(String.valueOf(params.get("destUrl")));
    }
    
    /**
     * 裁剪图片-来源是图片流
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @throws IOException 
     */
    //public void imageCropFromBuff(long width1, long height1, long x1, long y1, BufferedImage image, String dest) throws IOException {
    public void imageCropFromBuff(Map<String,Object> params) throws IOException {
        Thumbnails thumbnails = new Thumbnails();
        String destUrl = String.valueOf(params.get("destUrl"));
        BufferedImage image = (BufferedImage) params.get("image");
        int defaultStartX = Dict.DEFAULT_POS.START_X;
        int defaultStartY = Dict.DEFAULT_POS.START_Y;
        //指定坐标
        int width = Integer.parseInt(String.valueOf(params.get("width")));
        int height = Integer.parseInt(String.valueOf(params.get("height")));
        int start_x = Integer.parseInt(String.valueOf(params.get("start_x")))<0?defaultStartX:Integer.parseInt(String.valueOf(params.get("start_x")));
        int start_y = Integer.parseInt(String.valueOf(params.get("start_y")))<0?defaultStartY:Integer.parseInt(String.valueOf(params.get("start_y")));
        if(start_x==0 && start_y==0){
            BufferedImage bi = thumbnails.of(image).sourceRegion(start_x,start_y,width,height).scale(1f).asBufferedImage();
            BufferedImage inputImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            Graphics graphics = inputImage.getGraphics();
            graphics.setColor(new Color(255, 255, 255));  
            graphics.fillRect(defaultStartX, defaultStartY, width,height);
            graphics.drawImage(bi, defaultStartX, defaultStartY, width,height, null); //画图
            ImageIO.write(inputImage, Dict.IMAGE_FORMAT.PNG, new File(destUrl));
        }else{
            thumbnails.of(image).sourceRegion(start_x,start_y,width,height).scale(1f).toFile(destUrl);
        }
    }
    
    /**
     * 裁剪图片-来源是图片流,对图片进行质量压缩
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @throws IOException 
     */
    //public void imageCropFromBuffQuality(long width1, long height1, long x1, long y1, BufferedImage image, String dest,String outputQuality) throws IOException {
    public void imageCropFromBuffQuality(Map<String,Object> params) throws IOException {
    	Thumbnails thumbnails = new Thumbnails();
        float quality = Float.parseFloat(String.valueOf(params.get("outputQuality")));
        int width = Integer.valueOf(String.valueOf(params.get("width")));
        int height = Integer.valueOf(String.valueOf(params.get("height")));
        int x = Integer.valueOf(String.valueOf(params.get("x1")));
        int y = Integer.valueOf(String.valueOf(params.get("y1")));
        thumbnails.of((BufferedImage)params.get("image"))
        .sourceRegion(x,y,width,height)
        .scale(quality)
        .outputQuality(quality)
        .toFile(String.valueOf(params.get("destUrl")));
    }
    
    /**
     * 裁剪图片-来源是URL返回文件流
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @return BufferedImage 文件流
     * @throws IOException 
     */
    public BufferedImage imageCropBuffered(long width1, long height1, long x1, long y1, String source) throws IOException {
        BufferedImage bi = null;
        Thumbnails thumbnails = new Thumbnails();
        //指定坐标
        if (x1 < 0) {
            x1 = 0;
        }
        if (y1 < 0) {
            y1 = 0;
        }
        
        int width = Integer.valueOf(String.valueOf(width1));
        int height = Integer.valueOf(String.valueOf(height1));
        int x = Integer.valueOf(String.valueOf(x1));
        int y = Integer.valueOf(String.valueOf(y1));
        bi = thumbnails.of(source).sourceRegion(x,y,width,height).scale(1f).asBufferedImage();
        return bi;
    }
    
    /**
     * 裁剪图片-来源是图片流返回文件流
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @return BufferedImage 文件流
     * @throws IOException 
     */
    public BufferedImage imageCropBuffered(long width1, long height1, long x1, long y1, BufferedImage source) throws IOException {
        BufferedImage bi = null;
        Thumbnails thumbnails = new Thumbnails();
        //指定坐标
        if (x1 < 0) {
            x1 = 0;
        }
        if (y1 < 0) {
            y1 = 0;
        }
        
        int width = Integer.valueOf(String.valueOf(width1));
        int height = Integer.valueOf(String.valueOf(height1));
        int x = Integer.valueOf(String.valueOf(x1));
        int y = Integer.valueOf(String.valueOf(y1));
        bi = thumbnails.of(source).sourceRegion(x,y,width,height).scale(1f).asBufferedImage();
        BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        Graphics graphics = grayImage.getGraphics();
        graphics.setColor(new Color(255, 255, 255));  
        graphics.fillRect(0, 0, width,height);
        graphics.drawImage(bi, 0, 0, width,height, null); //画图        
        for(int i= 0 ; i < width ; i++){
            for(int j = 0 ; j < height; j++){
               int rgb = grayImage.getRGB(i, j);
               grayImage.setRGB(i, j, rgb);
            }  
        }

        return grayImage;
    }

    /**
     * 裁剪图片-从右上角开始
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @param dest 裁剪后图片文件路径
     * @throws IOException 
     * @throws NumberFormatException 
     */
    public void imageCropRight(int width, int height, String source, String dest) throws NumberFormatException, IOException {
        Thumbnails thumbnails = new Thumbnails();
        thumbnails.of(source).sourceRegion(Positions.TOP_RIGHT,width,height).scale(1f).toFile(dest);
    }
    
    /**
     * 裁剪图片-从右上角开始
     * @param width 裁剪后图片宽度
     * @param height 裁剪后图片高度
     * @param x x轴偏移量
     * @param y y轴偏移量
     * @param source 源图片文件路径
     * @return 文件流
     * @throws IOException 
     * @throws NumberFormatException 
     */
    public BufferedImage imageCropRight(long width, long height, long x, long y, String source) throws NumberFormatException, IOException {
        Thumbnails thumbnails = new Thumbnails();
        BufferedImage bi = null;
        bi = thumbnails.of(source).sourceRegion(Positions.TOP_RIGHT,Integer.valueOf(String.valueOf(width)),Integer.valueOf(String.valueOf(height))).scale(1f).asBufferedImage();
        return bi;
    }
    
    /**
     * 图片裁剪方法-用于校验正面后裁剪
     * @param record 答卷记录
     * @param image 图片流
     * @param kmdjDiffAll 答卷比对偏差集
     * @param cjcsMap 裁剪参数集
     * @param ksbh 考号
     * @param ksxxMap 考生信息集
     * @throws IOException 
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    @SuppressWarnings("unchecked")
	public void cropImageForZm(Map<String,Object> map) throws IOException{
    	CoursePaperDetail record = (CoursePaperDetail) map.get("record");
        Map<String,Map<String,Map<String,Object>>> cjcsMap = (Map<String, Map<String, Map<String,Object>>>) map.get("cjcsMap");
        Map<String,String> ksxxMap = (Map<String, String>) map.get("ksxxMap");
        String studentNo = (String) map.get("studentNo");
        
    	Map<String, Map<String,Object>> singleMap = cjcsMap.get("singleMap");//单选题
        Map<String, Map<String,Object>> moreMap = cjcsMap.get("moreMap");//多选题
        Map<String, Map<String,Object>> zgMap1 = cjcsMap.get("zgMap1");//正面主观题
        String batchId = ksxxMap.get("batchId");
        String gradeNo = ksxxMap.get("gradeNo");
        String courseNo = ksxxMap.get("courseNo");
        String dirPath = MessageUtil.getExtConfig("fj.course.paper.crop.url");
        
        String relativePath = batchId+"_"+courseNo+"/";//截图后图片存放相对目录
        String rootDirUrl = dirPath + relativePath;//截图后图片存放实际目录
        //创建图片裁剪存放目录
        File picFile = new File(rootDirUrl);
        if(!picFile.exists()){
            picFile.mkdirs();
        }
        
        //裁剪图片
        String djid = (String) record.getId();//答卷id
        String tempId = (String) record.getCourseTemplateId();//科目模板id
        String filePath = dirPath + record.getFilePath();//答卷存储路径
        Map<String,String> argsMap = new HashMap<String,String>();
        argsMap.putAll(ksxxMap);
        argsMap.put("relativePath", relativePath);
        argsMap.put("rootDirUrl", rootDirUrl);
        argsMap.put("saveName", filePath);
        argsMap.put("kmmbid", tempId);
        argsMap.put("djid", djid);
        
        //计算出客观题大区坐标点
        long px1=0,px2=0,py1=0,py2=0;
        int num = 0;//计数
        Map<String,Integer> params = new HashMap<String,Integer>();
        Map<String, Object> criteria = new HashMap<String, Object>();
        criteria.put("gradeNo", gradeNo);
        criteria.put("courseNo", courseNo);
        criteria.put("batchId", batchId);
        String[] tempIds = {tempId};
        criteria.put("tempIds", Arrays.asList(tempIds));
        criteria.put("studentNo", studentNo);
        this.coursePaperService.deleteKsbhExists(criteria);
        
        map.put("argsMap", argsMap);
        map.put("zfmType",1);
        //单选区
        if(!singleMap.isEmpty()){
        	map.put("lx",3);
            for(Entry<String, Map<String,Object>> entry : singleMap.entrySet()){
                map.put("record",entry.getValue());
                params = this.imgCut(map);
                int _px1 = params.get("px1");
                int _px2 = params.get("px2");
                int _py1 = params.get("py1");
                int _py2 = params.get("py2");System.out.println("_px1="+_px1+",_px2="+_px2+",_py1="+_py1+",_py2="+_py2);
                if(num==0){
                    px1 = _px1;
                    px2 = _px2;
                    py1 = _py1;
                    py2 = _py2;
                }else{
                    if(_px1 < px1){
                        px1 = _px1;
                    }
                    if(_py1 < py1){
                        py1 = _py1;
                    }
                    if(_px2 > px2){
                        px2 = _px2;
                    }
                    if(_py2 > py2){
                        py2 = _py2;
                    }
                    System.out.println("*****px1="+px1+",px2="+px2+",py1="+py1+",py2="+py2);
                }
                num++;
            }
        }
        
        //多选区
        if(!moreMap.isEmpty()){
        	map.put("lx",4);
            for(Entry<String, Map<String,Object>> entry : moreMap.entrySet()){
            	map.put("record",entry.getValue());
            	params = this.imgCut(map);
                int _px1 = params.get("px1");
                int _px2 = params.get("px2");
                int _py1 = params.get("py1");
                int _py2 = params.get("py2");
                if(num==0){
                    px1 = _px1;
                    px2 = _px2;
                    py1 = _py1;
                    py2 = _py2;
                }else{
                    if(_px1 < px1){
                        px1 = _px1;
                    }
                    if(_py1 < py1){
                        py1 = _py1;
                    }
                    if(_px2 > px2){
                        px2 = _px2;
                    }
                    if(_py2 > py2){
                        py2 = _py2;
                    }
                }
                num++;
            }
        }
        
        if(num>0){
            //裁剪客观题大区
        	System.out.println("px1="+px1+",px2="+px2+",py1="+py1+",py2="+py2);
            argsMap.put("px1", String.valueOf(px1));
            argsMap.put("py1", String.valueOf(py1));
            argsMap.put("px2", String.valueOf(px2));
            argsMap.put("py2", String.valueOf(py2));
            argsMap.put("outputQuality", "0.5f");
            map.put("argsMap",argsMap);
            map.put("lx",-1);
            map.remove("record");
            this.imgCut(map);
            argsMap.remove("outputQuality");
            num=0;
        }
        
        //主观题-正面
        if(!zgMap1.isEmpty()){
            argsMap.put("outputQuality", "0.6f");
            map.put("argsMap",argsMap);
            map.put("lx",5);
            for(Entry<String, Map<String,Object>> entry : zgMap1.entrySet()){
            	map.put("record",entry.getValue());
            	this.imgCut(map);
            }
            argsMap.remove("outputQuality");
        }
        
        //更新答卷表是否裁剪状态
        //if(session==null){//手工校正调用
        	/*CoursePaperDetail detail = new CoursePaperDetail();
        	detail.setIsCrop(1);
        	detail.setId(djid);
        	this.coursePaperService.updatePaperDetailStatus(detail);*/
            //Db.update(uSql);
            //log.info(uSql);
        //}else{//自动校验调用
            /*ConcurrentHashMap<String,String> cropUpdateSqlMapSession = (ConcurrentHashMap<String, String>)session.getAttribute("cropUpdateSqlMapSession");
            cropUpdateSqlMapSession.put(UUID.randomUUID().toString(), uSql);
            session.setAttribute("cropUpdateSqlMapSession", cropUpdateSqlMapSession);*/
        //}
    }
    
    /**
     * 图片裁剪方法-用于校验反面后裁剪
     * @param record 答卷记录
     * @param kmdjDiffAll 科目答卷比对偏差集
     * @param cjcsMap 裁剪参数集
     * @param ksbh 考号
     * @param ksxxMap 考生信息集
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public void cropImageForFm(HttpSession session,CoursePaperDetail record,Map<String,Map<String,Integer>> kmdjDiffAll,Map<String,Map<String,Object>> cjcsMap,
    @SuppressWarnings("unchecked")
	public void cropImageForFm(Map<String,Object> map) throws IOException{
    	CoursePaperDetail record = (CoursePaperDetail) map.get("record");
        Map<String,Map<String,Object>> cjcsMap = (Map<String, Map<String, Object>>) map.get("cjcsMap");
        Map<String,String> ksxxMap = (Map<String, String>) map.get("ksxxMap");
        String dirPath = MessageUtil.getExtConfig("fj.course.paper.crop.url");
    	Map<String,Object> zgMap2 = cjcsMap.get("zgMap2");//反面主观题
        map.putAll(ksxxMap);
        String relativePath = ksxxMap.get("batchId")+"_"+ksxxMap.get("courseNo")+"/";//截图后图片存放相对目录
        String rootDirUrl = dirPath + relativePath;//截图后图片存放实际目录
        //创建图片裁剪存放目录
        File picFile = new File(rootDirUrl);
        if(!picFile.exists()){
            picFile.mkdirs();
        }
        
        //裁剪图片
        String djid = (String) record.getId();//答卷id
        String filePath = dirPath + record.getFilePath();//答卷存储路径
        String tempId = (String) record.getCourseTemplateId();//科目模板id
        Map<String,Object> argsMap = new HashMap<String,Object>();
        argsMap.putAll(ksxxMap);
        argsMap.put("relativePath", relativePath);
        argsMap.put("rootDirUrl", rootDirUrl);
        argsMap.put("saveName", filePath);
        argsMap.put("djid", djid);
        String[] tempIds = {tempId};
        map.put("tempIds", Arrays.asList(tempIds));
        this.coursePaperService.deleteKsbhExists(map);
        
        //主观题-反面
        if(!zgMap2.isEmpty()){
            argsMap.put("outputQuality", "0.6f");
            map.put("argsMap", argsMap);
            map.put("zfmType",2);
            map.put("lx",5);
            for(Entry<String, Object> entry : zgMap2.entrySet()){
            	map.put("record",entry.getValue());
            	this.imgCut(map);
            }
            argsMap.remove("outputQuality");
        }
        
        //更新答卷表是否裁剪状态
        //if(session==null){//手工校正调用
        	/*CoursePaperDetail detail = new CoursePaperDetail();
        	detail.setIsCrop(1);
        	detail.setId(djid);
        	this.coursePaperService.updatePaperDetailStatus(detail);*/
            //Db.update(uSql);
            //log.info(uSql);
        //}else{//自动校验调用
            /*ConcurrentHashMap<String,String> cropUpdateSqlMapSession = (ConcurrentHashMap<String, String>)session.getAttribute("cropUpdateSqlMapSession");
            cropUpdateSqlMapSession.put(UUID.randomUUID().toString(), uSql);
            session.setAttribute("cropUpdateSqlMapSession", cropUpdateSqlMapSession);*/
        //}
    }
    
    /**
     * 图片裁剪方法-用于答卷校验后裁剪
     * @param r 答卷记录
     * @param image 图片流
     * @param argsMap 参数集
     * @param kmdjDiffAll 科目答卷偏差集
     * @param ksbh 考号
     * @param zfm 正反面
     * @param lx 区域类型
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    @SuppressWarnings("unchecked")
	public Map<String,Integer> imgCut(Map<String,Object> map) throws IOException{
    //public Map<String,Long> imgCut(HttpSession session,Map<String,Object> r,BufferedImage image,Map<String,String> argsMap,Map<String,Map<String,Integer>> kmdjDiffAll,String ksbh,int zfm,int lx) throws IOException{
        Map<String,Integer> result = new HashMap<String,Integer>();
        Map<String,Object> record = (Map<String, Object>) map.get("record");
        BufferedImage image = (BufferedImage) map.get("image");
        Map<String,String> argsMap = (Map<String, String>) map.get("argsMap");
        Map<String,Map<String,Integer>> kmdjDiffAll = (Map<String, Map<String, Integer>>) map.get("kmdjDiffAll");
        String studentNo = (String) map.get("studentNo");
        Integer zfmType = Integer.valueOf(map.get("zfmType")+"");
        Integer lx = Integer.valueOf(map.get("lx")+"");
        
        //获取模板对应的截取范围
        String areaId = "";
        String imgName = UUIDUtils.UUID()+ "." +Dict.IMAGE_FORMAT.PNG;
        String sourceUrl = argsMap.get("saveName");//源路径
        String destUrl = argsMap.get("rootDirUrl")+imgName;//目标路径
        String relativePath = argsMap.get("relativePath") + imgName;//文件相对路径
        String djid = argsMap.get("djid");
        int x1=0,y1=0,x2=0,y2=0,width=0,height=0;
        if(record != null){
            areaId = record.get("id")+"";//裁剪区域id
            Map<String, Integer> diffMap = kmdjDiffAll.get(djid);
            int p_x = diffMap.get("p_x");
            int p_y = diffMap.get("p_y");
            
            x1 = Integer.valueOf(record.get("x1")+"") + p_x;
            x2 = Integer.valueOf(record.get("x2")+"") + p_x;
            y1 = Integer.valueOf(record.get("y1")+"") + p_y;
            y2 = Integer.valueOf(record.get("y2")+"") + p_y;
            width = x2 - x1;
            height = y2 - y1;
        }else{
            x1 = Integer.valueOf(argsMap.get("px1"));
            y1 = Integer.valueOf(argsMap.get("py1"));
            x2 = Integer.valueOf(argsMap.get("px2"));
            y2 = Integer.valueOf(argsMap.get("py2"));
            if(x1<100){
                x1 = 0;
            }else{
                x1 = x1 - 100;
            }
            if(y1<100){
                y1 = 0;
            }else{
                y1 = y1 - 100;
            }
            x2 = x2 + 100;
            y2 = y2 + 100;
            width = x2 - x1;//宽度
            height = y2 - y1;//高度
        }
        
        Map<String,Object> params1 = new HashMap<String,Object>();
        if(argsMap.get("outputQuality")==null){
        	params1.put("width", width);
        	params1.put("height", height);
        	params1.put("start_x", x1);
        	params1.put("start_y", y1);
        	params1.put("sourceUrl", sourceUrl);
        	params1.put("destUrl", destUrl);
        	params1.put("image", image);
            if(zfmType == 1){
                imageCropFromBuff(params1);//正面裁剪
            }else{
                imageCropFromUrl(params1);//反面裁剪
            }
        }else{//裁剪图像压缩质量
            params1.clear();
            params1.put("outputQuality", argsMap.get("outputQuality"));
            params1.put("width", width);
            params1.put("height", height);
            params1.put("x1", x1);
            params1.put("y1", y1);
            params1.put("image", image);
            params1.put("destUrl", destUrl);
            if(zfmType == 1){
                imageCropFromBuffQuality(params1);//正面裁剪
            }else{
            	params1.put("sourceUrl", sourceUrl);
            	imageCropFromUrlQuality(params1);//反面裁剪
            }
        }
        
        //将裁剪后的图片信息保存到数据表中
        CoursePaperCrop entity = new CoursePaperCrop();
        entity.setStudentNo(studentNo);
        entity.setAreaId(areaId);
        entity.setOwner(djid);
        entity.setFilePath(relativePath);
        entity.setStatus(0);
        entity.setWidth(width);
        entity.setHeight(height);
        entity.setType(lx);
        this.coursePaperService.insertCoursePaperCrop(entity);
        
        result.put("px1", x1);
        result.put("px2", x2);
        result.put("py1", y1);
        result.put("py2", y2);
        return result;
    }

    /**
     * 裁剪指定区域图片
     * @param r 模板记录
     * @param kmdjUrl 答卷路径
     * @param p_x X偏移量
     * @param p_y Y偏移量
     * @param type 裁剪区域类型
     * @return
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,String> getDjKsbhBufferedImage(Map<String,Object> r,String kmdjUrl,int p_x,int p_y,int type){
    public Map<String,Object> getPositionBufferedImage(Map<String,Object> criteria){
    	String fileTempDir = MessageUtil.getExtConfig("fj.temp.pic.url");
    	CourseTemplateArea record = (CourseTemplateArea) criteria.get("record");
    	Integer lx = Integer.parseInt(criteria.get("lx")+"");
    	Integer offsetX = Integer.parseInt(criteria.get("offsetX")+"");
    	Integer offsetY = Integer.parseInt(criteria.get("offsetY")+"");
    	
        //获取裁剪区域坐标点
        Map<String,Object> params = new HashMap<String,Object>();
        int x1 = Integer.parseInt(String.valueOf(record.getX1()));
        int x2 = Integer.parseInt(String.valueOf(record.getX2()));
        int y1 = Integer.parseInt(String.valueOf(record.getY1()));
        int y2 = Integer.parseInt(String.valueOf(record.getY2()));
        
        //根据偏差值计算出每个考生答卷实际坐标点
        x1 += offsetX;
        x2 += offsetX;
        y1 += offsetY;
        y2 += offsetY;
        if(lx == 1){
            //考号区域,四周各加100PX，确保考号区域截取完整
            x1 -= 100; 
            x2 += 100; 
            y1 -= 100; 
            y2 += 100; 
        }else if(lx == 9){
            //缺考区域,上下右加100PX，左边加300PX
            x1 = x1-300 < 0 ? 0 : x1-300; 
            x2 += 100; 
            y1 -= 100; 
            y2 += 100; 
        }
        
        int width = x2 - x1;
        params.put("width", width);
        params.put("height", y2 - y1);
        params.put("start_x", x1);
        params.put("start_y", y1);
            
        //裁剪考生编号区域
        String imgName = UUIDUtils.UUID()+ "."+Dict.IMAGE_FORMAT.PNG;
        params.put("imgName", imgName);
        params.put("sourceUrl", criteria.get("sourceUrl"));
        params.put("destUrl", fileTempDir);//临时图片存放路径
        this.cropPos(params);
        
        params.clear();
        params.put("imgUrl", imgName);
        params.put("width", width);
        return params;
    }

}
